/*******************************************************************************
* Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.internal.image;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
class PngPlteChunk extends PngChunk {
int paletteSize;
PngPlteChunk(PaletteData palette) {
super(palette.getRGBs().length * 3);
paletteSize = length / 3;
setType(TYPE_PLTE);
setPaletteData(palette);
setCRC(computeCRC());
}
PngPlteChunk(byte[] reference){
super(reference);
paletteSize = length / 3;
}
@Override
int getChunkType() {
return CHUNK_PLTE;
}
/**
* Get the number of colors in this palette.
*/
int getPaletteSize() {
return paletteSize;
}
/**
* Get a PaletteData object representing the colors
* stored in this PLTE chunk.
* The result should be cached as the PLTE chunk
* does not store the palette data created.
*/
PaletteData getPaletteData() {
RGB[] rgbs = new RGB[paletteSize];
// int start = DATA_OFFSET;
// int end = DATA_OFFSET + length;
for (int i = 0; i < rgbs.length; i++) {
int offset = DATA_OFFSET + (i * 3);
int red = reference[offset] & 0xFF;
int green = reference[offset + 1] & 0xFF;
int blue = reference[offset + 2] & 0xFF;
rgbs[i] = new RGB(red, green, blue);
}
return new PaletteData(rgbs);
}
/**
* Set the data of a PLTE chunk to the colors
* stored in the specified PaletteData object.
*/
void setPaletteData(PaletteData palette) {
RGB[] rgbs = palette.getRGBs();
for (int i = 0; i < rgbs.length; i++) {
int offset = DATA_OFFSET + (i * 3);
reference[offset] = (byte) rgbs[i].red;
reference[offset + 1] = (byte) rgbs[i].green;
reference[offset + 2] = (byte) rgbs[i].blue;
}
}
/**
* Answer whether the chunk is a valid PLTE chunk.
*/
@Override
void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
// A PLTE chunk is invalid if no IHDR has been read or if any PLTE,
// IDAT, or IEND chunk has been read.
if (!readState.readIHDR
|| readState.readPLTE
|| readState.readTRNS
|| readState.readIDAT
|| readState.readIEND)
{
SWT.error(SWT.ERROR_INVALID_IMAGE);
} else {
readState.readPLTE = true;
}
super.validate(readState, headerChunk);
// Palettes cannot be included in grayscale images.
//
// Note: just ignore the palette.
// if (!headerChunk.getCanHavePalette()) SWT.error(SWT.ERROR_INVALID_IMAGE);
// Palette chunks' data fields must be event multiples
// of 3. Each 3-byte group represents an RGB value.
if (getLength() % 3 != 0) SWT.error(SWT.ERROR_INVALID_IMAGE);
// Palettes cannot have more entries than 2^bitDepth
// where bitDepth is the bit depth of the image given
// in the IHDR chunk.
if (1 << headerChunk.getBitDepth() < paletteSize) {
SWT.error(SWT.ERROR_INVALID_IMAGE);
}
// Palettes cannot have more than 256 entries.
if (256 < paletteSize) SWT.error(SWT.ERROR_INVALID_IMAGE);
}
@Override
void contributeToString(StringBuffer buffer) {
buffer.append("\n\tPalette size:");
buffer.append(paletteSize);
}
}